package com.qk.management.aspect;

import com.qk.entity.Clue;
import com.qk.management.annotation.ClueStateMachineTransition;
import com.qk.management.mapper.ClueMapper;
import com.qk.management.statemachine.event.ClueEvent;
import com.qk.management.statemachine.executor.StateMachineExecutor;
import com.qk.management.statemachine.listener.ClueStateChangeListener;
import com.qk.management.statemachine.status.ClueStatus;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.statemachine.config.StateMachineFactory;
import org.springframework.stereotype.Component;

@Aspect
@Slf4j
@Component
@RequiredArgsConstructor
public class ClueStateMachineAspect {

    private final StateMachineFactory<ClueStatus, ClueEvent> clueStateMachineFactory;
    private final StateMachineExecutor stateMachineExecutor;
    private final ClueStateChangeListener clueStateChangeListener;
    private final ClueMapper clueMapper;

    // 修改StateMachineAspect.java
    @Around("@annotation(clueStateMachineTransition)")
    public Object handleClueStateMachineTransition(ProceedingJoinPoint joinPoint,
                                                   ClueStateMachineTransition clueStateMachineTransition) throws Throwable {

        // 解析machineId
        String machineId = parseExpression(joinPoint, clueStateMachineTransition.machineId());

        // 获取当前状态
        ClueStatus currentState;
        if (clueStateMachineTransition.queryFromDatabase()) {
            Clue clue = clueMapper.selectById(Integer.valueOf(machineId));
            currentState = ClueStatus.fromCode(clue.getStatus());
        } else {
            String statusStr = parseExpression(joinPoint, clueStateMachineTransition.currentState());
            currentState = ClueStatus.fromCode(Integer.parseInt(statusStr));
        }

        // 执行状态转换
        boolean accepted = stateMachineExecutor
                .withFactory(clueStateMachineFactory)
                .withListener(clueStateChangeListener)
                .withHeader("clueId", machineId)
                .withMachineId(machineId)
                .withCurrentState(currentState)
                .withEvent(clueStateMachineTransition.event())
                .execute();

        if (!accepted) {
            throw new RuntimeException("状态转换失败");
        }

        // 执行原方法
        return joinPoint.proceed();
    }

    private String parseExpression(ProceedingJoinPoint joinPoint, String expression) {
        if (expression == null || expression.isEmpty()) {
            return null;
        }

        // 使用Spring Expression Language解析表达式
        StandardEvaluationContext context = new StandardEvaluationContext();

        // 获取方法签名和参数
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] paramNames = signature.getParameterNames();
        Object[] args = joinPoint.getArgs();

        // 将参数添加到上下文
        for (int i = 0; i < paramNames.length; i++) {
            context.setVariable(paramNames[i], args[i]);
        }

        // 解析表达式
        ExpressionParser parser = new SpelExpressionParser();
        return parser.parseExpression(expression).getValue(context, String.class);
    }
}
